<template>
  <div class="image-uploader">
    <el-upload
      ref="uploadRef"
      :action="uploadUrl"
      :headers="uploadHeaders"
      :show-file-list="false"
      :before-upload="beforeUpload"
      :on-success="handleSuccess"
      :on-error="handleError"
      :accept="accept"
      :disabled="disabled"
      class="upload-area"
    >
      <div class="upload-content">
        <div v-if="!imageUrl" class="upload-placeholder">
          <el-icon class="upload-icon"><Plus /></el-icon>
          <div class="upload-text">点击上传图片</div>
          <div class="upload-hint">支持 JPG、PNG、GIF 格式，大小不超过 2MB</div>
        </div>
        <div v-else class="image-preview">
          <img :src="imageUrl" alt="预览图" class="preview-image" />
          <div class="image-overlay">
            <el-icon class="change-icon"><Edit /></el-icon>
            <span>更换图片</span>
          </div>
        </div>
      </div>
    </el-upload>
    
    <!-- 图片操作按钮 -->
    <div v-if="imageUrl" class="image-actions">
      <el-button 
        type="primary" 
        size="small" 
        @click="previewImage"
        :icon="View"
      >
        预览
      </el-button>
      <el-button 
        type="danger" 
        size="small" 
        @click="removeImage"
        :icon="Delete"
      >
        删除
      </el-button>
    </div>

    <!-- 图片预览对话框 -->
    <el-dialog v-model="previewVisible" title="图片预览" width="600px" center>
      <div class="preview-dialog">
        <img :src="imageUrl" alt="预览图" class="dialog-image" />
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { ref, computed, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { Plus, Edit, View, Delete } from '@element-plus/icons-vue'
import { getToken } from '@/utils/auth'

export default {
  name: 'ImageUploader',
  components: {
    Plus,
    Edit,
    View,
    Delete
  },
  props: {
    modelValue: {
      type: String,
      default: ''
    },
    disabled: {
      type: Boolean,
      default: false
    },
    accept: {
      type: String,
      default: 'image/*'
    },
    maxSize: {
      type: Number,
      default: 2 * 1024 * 1024 // 2MB
    }
  },
  emits: ['update:modelValue', 'upload-success', 'upload-error', 'remove'],
  setup(props, { emit }) {
    const uploadRef = ref(null)
    const imageUrl = ref(props.modelValue)
    const previewVisible = ref(false)

    // 上传URL
    const uploadUrl = computed(() => {
      return `${import.meta.env.VITE_API_BASE_URL || 'http://localhost:8080'}/api/upload/image`
    })

    // 上传请求头
    const uploadHeaders = computed(() => {
      const token = getToken()
      return token ? { Authorization: `Bearer ${token}` } : {}
    })

    // 监听modelValue变化
    watch(() => props.modelValue, (newVal) => {
      imageUrl.value = newVal
    })

    // 监听imageUrl变化
    watch(imageUrl, (newVal) => {
      emit('update:modelValue', newVal)
    })

    // 上传前验证
    const beforeUpload = (file) => {
      // 验证文件类型
      const isImage = file.type.startsWith('image/')
      if (!isImage) {
        ElMessage.error('只能上传图片文件！')
        return false
      }

      // 验证文件大小
      const isLt2M = file.size <= props.maxSize
      if (!isLt2M) {
        ElMessage.error(`图片大小不能超过 ${props.maxSize / 1024 / 1024}MB！`)
        return false
      }

      return true
    }

    // 上传成功
    const handleSuccess = (response) => {
      if (response.code === 200) {
        imageUrl.value = response.data
        ElMessage.success('图片上传成功！')
        emit('upload-success', response.data)
      } else {
        ElMessage.error(response.message || '上传失败！')
        emit('upload-error', response.message)
      }
    }

    // 上传失败
    const handleError = (error) => {
      console.error('上传失败:', error)
      ElMessage.error('图片上传失败，请重试！')
      emit('upload-error', error)
    }

    // 预览图片
    const previewImage = () => {
      if (imageUrl.value) {
        previewVisible.value = true
      }
    }

    // 删除图片
    const removeImage = async () => {
      try {
        if (imageUrl.value && imageUrl.value.startsWith('/uploads/')) {
          // 调用删除接口
          const response = await fetch(`${uploadUrl.value.replace('/image', '')}/image?url=${encodeURIComponent(imageUrl.value)}`, {
            method: 'DELETE',
            headers: uploadHeaders.value
          })
          
          if (response.ok) {
            ElMessage.success('图片删除成功！')
          }
        }
        
        imageUrl.value = ''
        emit('remove')
      } catch (error) {
        console.error('删除失败:', error)
        // 即使删除失败，也清除本地显示
        imageUrl.value = ''
        emit('remove')
      }
    }

    return {
      uploadRef,
      imageUrl,
      previewVisible,
      uploadUrl,
      uploadHeaders,
      beforeUpload,
      handleSuccess,
      handleError,
      previewImage,
      removeImage
    }
  }
}
</script>

<style scoped>
.image-uploader {
  width: 100%;
}

.upload-area {
  width: 100%;
}

.upload-content {
  border: 2px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: border-color 0.3s;
}

.upload-content:hover {
  border-color: #409eff;
}

.upload-placeholder {
  padding: 40px 20px;
  text-align: center;
  color: #8c939d;
}

.upload-icon {
  font-size: 28px;
  color: #8c939d;
  margin-bottom: 10px;
}

.upload-text {
  font-size: 16px;
  margin-bottom: 8px;
}

.upload-hint {
  font-size: 12px;
  color: #c0c4cc;
}

.image-preview {
  position: relative;
  width: 100%;
  height: 200px;
  overflow: hidden;
}

.preview-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.image-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: white;
  opacity: 0;
  transition: opacity 0.3s;
}

.image-preview:hover .image-overlay {
  opacity: 1;
}

.change-icon {
  font-size: 24px;
  margin-bottom: 8px;
}

.image-actions {
  margin-top: 10px;
  display: flex;
  gap: 10px;
  justify-content: center;
}

.preview-dialog {
  text-align: center;
}

.dialog-image {
  max-width: 100%;
  max-height: 400px;
  object-fit: contain;
}
</style> 